package com.lh.vo;

import com.alibaba.fastjson2.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.json.GsonJsonParser;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @author: linghao
 * @since: 2022/7/22
 */
public class XSSAndSqlUtil {

    public static boolean check(String value) {
        boolean flag = false;
        if (value != null) {
            value = value.toLowerCase();
            Pattern scriptPattern = Pattern.compile(
                    "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            // Avoid anything in a
            // src="http://www.yihaomen.com/article/java/..." type of
            // e-xpression
            scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            // Remove any lonesome </script> tag
            scriptPattern = Pattern.compile("</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            // Remove any lonesome <script ...> tag
            scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            // Avoid eval(...) expressions
            scriptPattern = Pattern.compile("eval\\((.*?)\\)",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            // Avoid e-xpression(...) expressions
            scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            // Avoid javascript:... expressions
            scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            // Avoid vbscript:... expressions
            scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            // Avoid onload= expressions
            scriptPattern = Pattern.compile("onload(.*?)=",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
            //sql inject
            scriptPattern = Pattern.compile("\\b(\\s*and\\s*|\\s*exec\\s*|\\s*insert\\s*|\\s*select\\s*|\\s*drop\\s*|\\s*grant\\s*|\\s*alter\\s*|\\s*" +
                    "delete\\s*|\\s*update\\s*|\\s*count\\s*|\\s*chr\\s*|\\s*mid\\s*|\\s*master\\s*|\\s*truncate\\s*|\\s*char\\s*|\\s*declare\\s*|\\s*or\\s*)\\b|(\\*|;|\\+)");
            flag = scriptPattern.matcher(value).find();
            if (flag) {
                return flag;
            }
        }
        return flag;
    }

    //fastJson版本  JSONValidator.from(val).getType()有bug  x v,汉子 开的string value不能被识别
    public static Set<Boolean> checkXSSAndSql(String json,Set<Boolean> resutleSet){
        if(JSON.isValidObject(json)){
            JSONObject jsonObject = JSON.parseObject(json);
            jsonObject.forEach((key,value)->{
                checkXSSAndSql(value.toString(),resutleSet);
                /*if(JSONValidator.Type.Value == JSONValidator.from(val).getType()){
                    System.out.println("jsonObject xxvalue="+val);
                }else{
                    getJsonValues(val);
                }*/
            });
        }else if(JSON.isValidArray(json)){
            JSONArray jsonArray = JSON.parseArray(json);
            jsonArray.stream().forEach(value->{
                checkXSSAndSql(value.toString(),resutleSet);
                /*if(JSONValidator.Type.Value == JSONValidator.from(val).getType()){
                    System.out.println("JSONArray xxvalue="+val);
                }else{
                    getJsonValues(val);
                }*/
            });
        }else{ //不是jsonobject 也不是jsonarray 即正常的value
            System.out.println("JSON xxvalue="+json);
            if(check(json)){
                resutleSet.add(Boolean.TRUE);
            }
        }
        return resutleSet;
    }


    public static void main(String[] args) {
        String str2 = "fsdfvbscriptfs:";
        String str = "{\"test\":\"test\",\"javascript:\":[{\"select\":\"发哪家覅进位加法IE文件发\",\"ortest4\":\"nihao4\",\"test3\":\"xxjavascript调度uu\",\"test6\":[\"javascript\",\"upd11ate\"]}]}";
        Set<Boolean> resutleSet = new HashSet<>();
        System.out.println(checkXSSAndSql(str2,resutleSet).contains(Boolean.TRUE));

        JSONObject o = new JSONObject();
        o.put("sss","ss");
        o.put("sss1","ss2");

        JSONArray array = new JSONArray();
        array.add("qwer");
        array.add("wrew");

        Map<String,Object> testMap = new HashMap<>();
        testMap.put("test1","www");
        testMap.put("test2","www");

        Set testSet = new HashSet();
        testSet.add("aaa");
        testSet.add("dsa");

        List<Map<String,Test>> list = new ArrayList<>();
//        list.add(testMap);
        Test t = new Test();
        t.setA(new String[]{"1","3","56","ty"});
        ArrayList<String> listT = new ArrayList<>();
        listT.add("tettest");
        listT.add("tettest1");
        listT.add("tettest3");
        t.setB(listT);
        Map<String,Test> map = new HashMap<>();
        map.put("qaz",t);
        list.add(map);

//        checkXSSAndSql(array.toJSONString());


//        System.out.println(check(str));
//        String s = JSON.toJSONString(str);
//        System.out.println(str);
//        System.out.println(s);
    }
}
